#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"qtimer.h"
#include <QDebug>
#include <QDateTime>
//#define test
#define   REPOLT()  if(!ifPause) m_CustomPlot->replot();
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_CustomPlot( 0 ),//刷新时间间隔，单位为毫秒
    timeInterval( 100 ),
    Value_P(30),Value_I(1),Value_D(4),VauleName1("TEST1"),VauleName2("TEST2")
{
    ui->setupUi(this);
    SystemInit();
    setMinimumWidth( 900 );
    m_CustomPlot = new QCustomPlot( this );
    setCentralWidget( m_CustomPlot );
    m_CustomPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes |
                                      QCP::iSelectLegend | QCP::iSelectPlottables);
    //图0曲线颜色及宽度设置
    m_CustomPlot->addGraph();
    m_CustomPlot->graph(0)->setName(VauleName1);
    QPen graphPen;
    graphPen.setColor(QColor(255, 0, 0));
    graphPen.setWidthF(2.5);
    m_CustomPlot->graph(0)->setPen(graphPen);
    //图1曲线颜色及宽度设置
    m_CustomPlot->addGraph();
    m_CustomPlot->graph(0)->setName(VauleName2);
    graphPen.setColor(QColor(0, 255, 0));
    graphPen.setWidthF(2.5);
    m_CustomPlot->graph(1)->setPen(graphPen);

    //设置坐标轴格式
    m_CustomPlot->xAxis->setTickLabelType( QCPAxis::ltDateTime );
    m_CustomPlot->xAxis->setDateTimeFormat( "hh:mm:ss:zzz" );
    m_CustomPlot->xAxis->setAutoTickStep( true );
    m_CustomPlot->yAxis->setAutoTickStep( true );

    //初始化文字显示对象
    m_ValueIndex1 = new QCPItemText( m_CustomPlot );
    m_ValueIndex2 = new QCPItemText( m_CustomPlot );
    //设置字体
    m_ValueIndex1->setFont(QFont(font().family(), 11));
    m_ValueIndex2->setFont(QFont(font().family(), 11));

    //初始化定时器
    timer = new QTimer(this);
    connect(timer, SIGNAL( timeout() ), this, SLOT( updatePlot() ) );
    timer->start( timeInterval );

    //显示小图画
    m_CustomPlot->legend->setVisible(true);
    m_CustomPlot->legend->setFont(QFont("Helvetica", 12));
    m_CustomPlot->legend->setRowSpacing(-3);

    //PID,刷新时间显示窗口
    m_CustomPlot->addGraph();
    m_CustomPlot->addGraph();
    m_CustomPlot->addGraph();
    m_CustomPlot->addGraph();
    m_CustomPlot->graph(2)->setName("P");
    m_CustomPlot->graph(3)->setName("I");
    m_CustomPlot->graph(4)->setName("D");
    m_CustomPlot->graph(4)->setName("timeInterval");
    connect(m_CustomPlot, SIGNAL(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*)), this, SLOT(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*)));
    connect(m_CustomPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,int,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*,int)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::SystemInit()
{
   qDebug()<<"SystemInit";
}

void MainWindow::graphClicked(QCPAbstractPlottable *plottable, int dataIndex)
{
  // since we know we only have QCPGraphs in the plot, we can immediately access interface1D()
  // usually it's better to first check whether interface1D() returns non-zero, and only then use it.
  //double dataValue = plottable->interface1D()->dataMainValue(dataIndex);
  QString message = QString("Clicked on graph '%1' at data point #%2 with value.").arg(plottable->name()).arg(dataIndex);
  ui->statusBar->showMessage(message, 2500);
}

//读取键盘
void MainWindow::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_Space:
        if(ifPause)
            ifPause=false;
        else
            ifPause=true;
        break;
    default:
        break;
    }
}

//在线修改PID,刷新时间，变量名
void MainWindow::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item)
{
  Q_UNUSED(legend)
  if (item)
  {
    QCPPlottableLegendItem *plItem = qobject_cast<QCPPlottableLegendItem*>(item);
    QString plname=plItem->plottable()->name();
    bool ok;
    if (plname[0]==VauleName1[0] ||plname[0]== VauleName2[0])
    {
        QString newName = QInputDialog::getText(this, "legendDoubleClick", "New graph name:", QLineEdit::Normal, plname, &ok);
        if (ok)
            if (plname[0]==VauleName1[0])
                VauleName1=newName;
            else
                VauleName2=newName;
    }
    else
    {
        double temp = QInputDialog::getDouble(this, "legendDoubleClick", "New Vaule:",0,-20000,20000,1,&ok);
        if (ok)
        {
          if (plname[0]=='P')
              Value_P=temp;
          if (plname[0]=='I')
              Value_I=temp;
          if (plname[0]=='D')
              Value_D=temp;
          if (plname[0]=='t')
          {
              timeInterval=temp;
              timer->start( timeInterval );
          }
        }
    }
  }
}

void MainWindow::append_data0(double num)
{
    Value_data_0=num;
}

void MainWindow::append_data1(double num)
{
    Value_data_1=num;
}

void MainWindow::updatePlot()
{
    /****获取横轴数值：时间***/
    //获取当前时间
    QTime tm = QTime::currentTime();
    //???不知道为什么，在将其放入显示栏后会自动加8小时，用hh:mm:ss时发现的
    int32_t seconds = 60 * 60 * (tm.hour()-8) + 60 * tm.minute() + tm.second();
    double timeValue = 1000 * seconds + tm.msec();
    timeValue/=1000;//???不知道为什么，这里需要除以1000才能正常显示，看别人程序里有这个
    // Add the time the x data buffer
    tmpXXData0.append( timeValue );

    //获取纵轴数值：数值
#ifdef test
    //测试用数值为80附近的随机值
    qreal r = static_cast<qreal>( rand() ) / RAND_MAX  ;
    // the next value will be 80 plus or minus 5
    qreal value = -80 + 5 * r;
    tmpYYData0.append( value );
    value-=20;
    tmpYYData1.append( value );
#else
    tmpYYData0.append( Value_data_0 );
    tmpYYData1.append( Value_data_1 );
#endif
    // X轴刷新时间：同时只显示最新的200个数据
    if( tmpXXData0.size() > 200 ){
        tmpXXData0.remove( 0 );
        tmpYYData0.remove( 0 );
        tmpYYData1.remove( 0 );
    }

    //画图像坐标轴
    m_CustomPlot->graph( 0 )->setData( tmpXXData0 , tmpYYData0 );
    m_CustomPlot->graph( 1 )->setData( tmpXXData0 , tmpYYData1 );
    //设定坐标轴范围,根据当前纵坐标值设定
    QVector<double>::iterator xMaxIt = std::max_element( tmpXXData0.begin() , tmpXXData0.end() );
    QVector<double>::iterator xMinIt = std::min_element( tmpXXData0.begin() , tmpXXData0.end() );
    QVector<double>::iterator yMaxIt0 = std::max_element( tmpYYData0.begin() , tmpYYData0.end() );
    QVector<double>::iterator yMaxIt1 = std::max_element( tmpYYData1.begin() , tmpYYData1.end() );
    QVector<double>::iterator yMinIt0 = std::min_element( tmpYYData0.begin() , tmpYYData0.end() );
    QVector<double>::iterator yMinIt1 = std::min_element( tmpYYData1.begin() , tmpYYData1.end() );


    qreal yPlotMin = 0;
    qreal yPlotMax = 0;
    qreal yPlotMax0 = *yMaxIt0;
    qreal yPlotMax1 = *yMaxIt1;
    qreal yPlotMin0 = *yMinIt0;
    qreal yPlotMin1 = *yMinIt1;

    if (yPlotMax0>yPlotMax1)
        yPlotMax=yPlotMax0;
    else
        yPlotMax=yPlotMax1;

    if (yPlotMin0>yPlotMin1)
        yPlotMin=yPlotMin1;
    else
        yPlotMin=yPlotMin0;

    qreal xPlotMin = *xMinIt;
    qreal xPlotMax = *xMaxIt;

    //显示文字时使用，防止靠在一起
    qreal yOffset = 0.3 * ( yPlotMax - yPlotMin ) ;
    qreal xOffset = 0.5 *( xPlotMax - xPlotMin );
    m_CustomPlot->xAxis->setRange( xPlotMin , xPlotMax + xOffset );
    m_CustomPlot->yAxis->setRange(yPlotMin , yPlotMax + yOffset);

//************************************************************//
    //以文字形式实时显示当前数值
    qreal indexX = tmpXXData0.last() + 0.1 * xOffset;
    qreal indexY0 = tmpYYData0.last() + 0.1 * yOffset;
    qreal indexY1 = tmpYYData1.last() + 0.1 * yOffset;
    //设置文字显示位置
    m_ValueIndex1->position->setCoords( indexX , indexY0 );
    m_ValueIndex2->position->setCoords( indexX , indexY1 );
    //设置文字显示内容
    m_ValueIndex1->setText(QString::number(tmpYYData0.last()));
    m_ValueIndex2->setText(QString::number(tmpYYData1.last()));
    //在小窗口实时显示
    m_CustomPlot->graph(0)->setName(QString(VauleName1+"  "+QString::number(tmpYYData0.last(),'f',3)));
    m_CustomPlot->graph(1)->setName(QString(VauleName2+"  "+QString::number(tmpYYData1.last(),'f',3)));
    m_CustomPlot->graph(2)->setName(QString("P  "+QString::number(Value_P)));
    m_CustomPlot->graph(3)->setName(QString("I   "+QString::number(Value_I)));
    m_CustomPlot->graph(4)->setName(QString("D  "+QString::number(Value_D)));
    m_CustomPlot->graph(5)->setName(QString("tI  "+QString::number(timeInterval)));
    // Update the plot widget
    REPOLT();
}
